package com.netnovelstore.service.impl;

import com.netnovelstore.config.JwtUtil;
import com.netnovelstore.dao.UserMapper;
import com.netnovelstore.pojo.Enum.ResultEnum;
import com.netnovelstore.pojo.Exception.NotDataException;
import com.netnovelstore.pojo.Result;
import com.netnovelstore.pojo.User;
import com.netnovelstore.service.UserService;
import com.netnovelstore.util.FileManager;
import com.netnovelstore.util.Md5;
import com.netnovelstore.util.RedisUtil;
import com.netnovelstore.viewObject.LoginResult;
import com.netnovelstore.viewObject.UserListResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;

@Service
@Slf4j
public class UserServiceImpl implements UserService {


    private UserMapper userMapper;

    private FileManager fileManager;

    private RedisUtil redisUtil;

    @Autowired
    public UserServiceImpl(UserMapper userMapper, FileManager fileManager, RedisUtil redisUtil) {
        this.userMapper = userMapper;
        this.fileManager = fileManager;
        this.redisUtil = redisUtil;
    }

    @Override
    public Result<LoginResult> Login(String username, String password) throws NotDataException {
        User user = userMapper.Login(username);
        if (user == null)
            throw new NotDataException("账号不存在");
        log.info(user.toString());
        String md5ByUsernameAndPassword = Md5.getMD5ByUsernameAndPassword(username, password);
        if (!md5ByUsernameAndPassword.equals(user.getPassword())) {
            throw new NotDataException("密码错误");
        }
        Result<LoginResult> result = Result.ok();
        LoginResult loginResult = new LoginResult();
        loginResult.setUser(user);
        if ("user".equals(user.getUserType())) {
            loginResult.setToken(createTokenByUser(user));
        } else if ("admin".equals(user.getUserType())) {
            loginResult.setToken(createTokenByAdmin(user));
        } else {
            throw new NullPointerException("用户身份异常");
        }
        result.setObjects(loginResult);
        return result;
    }

    private String createTokenByUser(User user) {
        String token = JwtUtil.createToken(user.getUserName());
        redisUtil.set(user.getUserName(), token, JwtUtil.expireTime);
        redisUtil.set(token, user, JwtUtil.expireTime);
        return token;
    }

    private String createTokenByAdmin(User user) {
        //一天
        String token = JwtUtil.createToken(user.getUserName(), 86400000L);
        redisUtil.set(token, user, 86400000L);
        redisUtil.set(user.getUserName(), token, 86400000L);
        return token;
    }

    @Override
    public Result<String> uploadProfile(MultipartFile multipartFile, String oldUserImg, String username) throws IOException {
        String newFilePath = fileManager.writeProfile(multipartFile);
        return Result.ok("imgs/" + newFilePath);
    }


    @Override
    public Result userRegistered(User user) throws SQLException {
        String md5Password = Md5.getMD5ByUsernameAndPassword(user.getUserName(), user.getPassword());
        user.setPassword(md5Password);

        log.info(user.toString());
        Boolean result = userMapper.insertUser(user);
        if (!result) {
            throw new SQLException("insert fail");
        }
        Result update_done = Result.ok();
        return update_done;
    }

    @Override
    public Result<String> addProfile(MultipartFile multipartFile) throws IOException {
        String profile = fileManager.writeProfile(multipartFile);
        return Result.ok("imgs/" + profile);
    }


    @Override
    public Result updateUserByNumber(User user) throws NotDataException, SQLException {
        if (user.getPassword() != null && user.getUserName() != null) {
            user.setPassword(
                    Md5.getMD5ByUsernameAndPassword(user.getUserName(), user.getPassword())
            );
        } else if (user.getPassword() == null) {
            user.setPassword(null);
        }
        User oldUser = userMapper.getUserByNumber(user.getUserNumber());
        if (oldUser == null) {
            throw new NotDataException("user undefined");
        }
        oldUser.updateUser(user);
//            log.info("[updateUser] => "+ oldUser);
        Boolean result = userMapper.updateUserByNumber(oldUser);

        if (!result) {
            throw new SQLException("update fail ");
        }
        return Result.ok();
    }

    @Override
    public Result delUserByNumberList(List<Integer> numberList) throws Exception {
        Boolean result = userMapper.delUserByNumberList(numberList);
        if (!result)
            throw new Exception("delete fail!");
        return Result.ok();
    }

    @Override
    public Result<UserListResult> getUserList(Integer currentPage, Integer pageSize) throws Exception {
        int pageStart = (currentPage - 1) * pageSize;

        log.info(String.format("[user]  ->  从%d 开始查", pageStart));
        List<User> userList = userMapper.getUserList(pageStart, pageSize);
        Integer total = userMapper.getCountUser();

        if (userList == null) {
            throw new Exception("result is null");
        }
        UserListResult userListResult = new UserListResult();
        userListResult.setUsers(userList);
        userListResult.setTotal(total);

        return new Result<>(userListResult, ResultEnum.SUCCESS.getDesc(), ResultEnum.SUCCESS.getCode());
    }

    @Override
    public Result<List<User>> searchUserByInfo(String keyword) throws Exception {
        List<User> user = userMapper.getUserByInfo(keyword);
        if (user == null) {
            throw new Exception("result is null");
        }
        Result<List<User>> result = Result.ok();
        result.setObjects(user);
        return result;
    }

    @Override
    public Result<Boolean> isExistByUserName(String userName) {
        Integer existByUserName = userMapper.isExistByUserName(userName);
        return Result.ok(existByUserName > 0);
    }

    @Override
    public Result<Boolean> updateNickName(HttpServletRequest request, HttpServletResponse response, Integer userNumber, String nickName) throws Exception {
        log.info("run service");
        if (!userMapper.updateNickName(userNumber, nickName)) {
            throw new NotDataException("update file");
        }
        return Result.ok(true);
    }

}
